package com.itheima.sh.exception;


import com.google.common.collect.ImmutableMap;
import com.itheima.sh.response.Result;
import com.itheima.sh.response.StatusCode;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.awt.*;

/**
 * 添加不可预知异常处理
 */
@RestControllerAdvice
public class ExceptionCatch {
    private static final Logger LOGGER = Logger.getLogger(ExceptionCatch.class);

    // 拦截的是 BusinessException 自定义异常
    @ExceptionHandler(BusinessException.class)
    public Result catchBusinessException(BusinessException ex){
        // 记日志，发短信/邮件
        LOGGER.error(ex);

        ex.getStatusCode();

        return Result.errorResult(ex.getStatusCode());
    }

    //使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点的一旦创建不可改变，并且线程安全
    private static ImmutableMap<Class<? extends Throwable>,Result> EXCEPTIONS;
    //使用builder来构建一个异常类型和错误代码的异常
    protected static ImmutableMap.Builder<Class<? extends  Throwable>,Result> builder =
            ImmutableMap.builder();

    //拦截的是Exception 不可预知异常
    @ExceptionHandler(Exception.class)
    public Result catchException(Exception ex){
        // 记日志,发短信/邮箱
        LOGGER.error(ex);

        if (EXCEPTIONS == null){
            EXCEPTIONS = builder.build();
        }

        // 1 先得到EXCEPTIONS 根据key 得到Result结果返回
        Result result = EXCEPTIONS.get(ex.getClass());
        if (result == null){
            // 2. 没有找到统一响应99999状态码
            result = Result.errorResult(StatusCode.SYS_ERROR);
        }
        return result;
    }

    static{
        //在这里加入一些基础的异常类型判断
        builder.put(HttpMessageNotReadableException.class,
                Result.errorResult(StatusCode.PARAM_INVALID));//无效参数
        builder.put(ArithmeticException.class,//算数异常
                Result.errorResult(StatusCode.ARITHMETIC_ERROR));
        builder.put(FontFormatException.class,
                Result.errorResult(StatusCode.FONTFORMAT_ERROR)); //格式异常
    }

}
